支持併發的程式語言當中,我們就會注意到資源競爭的問題,若沒有善用鎖可能會得到非預期的結果
我們用案例來解釋
x 變數預期應該為 15000 ,我們可以看到輸出的結果並非預期 15000
原因在多併發的過程當中,goruntine 在拿取 x 變數的值,也有其他的 goruntine 對 x 進行寫入
導致 x 的值拿到舊值,故在獲取及寫入的時候要進行加鎖
package main
import (
"fmt"
"sync"
)
var x = 0
var wg sync.WaitGroup
func add() {
for i := 0; i < 50000; i++ {
x = x + 1
}
wg.Done()
}
func main() {
wg.Add(3)
go add()
go add()
go add()
wg.Wait()
fmt.Println(x)
}
由上案例的結果
那我們來使用官方提供的 Data Race Detector 來驗證是否真的發生資源競爭
go run -race main.go
確實發現有顯示
可以使用 sync.Mutex 來進行上鎖、解鎖
package main
import (
"fmt"
"sync"
)
var x = 0
var wg sync.WaitGroup
var lock sync.Mutex
func add() {
for i := 0; i < 50000; i++ {
lock.Lock()
x = x + 1
lock.Unlock()
}
wg.Done()
}
func main() {
wg.Add(3)
go add()
go add()
go add()
wg.Wait()
fmt.Println(x)
}
用一個小例子談談 Golang 中的 Race Condition
Golang race detection